using System;
using System.Collections.Generic;
using System.Text;
using FinanceStats.DAL;
using Informatika.Common;
using FinanceStats.Entities;
using System.Data;

namespace FinanceStats.Business
{
    public class DataManager
    {
        # region singleton definition
        static readonly DataManager instance = new DataManager();

        public static DataManager Instance
        {
            get
            {
                return instance;
            }
        }
        static DataManager()
        {
        }
        # endregion

        public int CheckLogin(string username, string password)
        {
            int res = -1;
            try
            {
                res = UserDAO.CheckLogin(username, password);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error getting login credentials from database", ex);
                res = -1;
            }
            return res;
        }

        #region OutcomeGroup
        public List<OutcomeGroup> LoadOutcomeGroups()
        {
            List<OutcomeGroup> res = null;
            try
            {
                res = OutcomeGroupDAO.LoadOutcomeGroups();
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading outcome groups", ex);
                res = null;
            }
            return res;
        }

        public List<OutcomeGroup> LoadTopMonthlyGroups(int top, DateTime day)
        {
            List<OutcomeGroup> res = null;
            try
            {
                DateTime startDay = day;
                DateTime endDay = day;
                int month = startDay.Month;
                while (month == startDay.Month)
                {
                    startDay = startDay.AddDays(-1);
                }
                month = endDay.Month;
                while (month == endDay.Month)
                {
                    endDay = endDay.AddDays(1);
                }
                startDay.AddDays(1);
                endDay.AddDays(-1);

                string topstr = top == -1 ? "" : String.Format(" TOP {0}", top);
                res = OutcomeGroupDAO.LoadOutcomeGroups(topstr, startDay, endDay);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading outcome groups", ex);
                res = null;
            }
            return res;
        }
        public bool InsertOutcomeGroup(OutcomeGroup og)
        {
            bool res = false;
            try
            {
                res = OutcomeGroupDAO.InsertOutcomeGroup(og);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error inserting outcome group", ex);
                res = false;
            }
            return res;
        }

        public bool UpdateOutcomeGroup(OutcomeGroup og)
        {
            bool res = false;
            try
            {
                res = OutcomeGroupDAO.UpdateOutcomeGroup(og);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error updating outcome group", ex);
                res = false;
            }
            return res;
        }
        #endregion

        #region OutcomeItem
        
        public List<OutcomeItem> LoadOutcomeItems()
        {
            return LoadOutcomeItems(-1);
        }

        public List<OutcomeItem> LoadOutcomeItems(int groupID)
        {
            List<OutcomeItem> res = null;
            try
            {
                res = OutcomeItemsDAO.LoadOutcomeItems(groupID);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading outcome groups", ex);
                res = null;
            }
            return res;
        }

        public Dictionary<string, int> LoadItemNames()
        {
            Dictionary<string, int> res = null;
            try
            {
                res = OutcomeItemsDAO.LoadNamesDictionary();
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading names dicitonary", ex);
                res = null;
            }
            return res;
        }
        public bool InsertOutcomeItem(OutcomeItem oi)
        {
            bool res = false;
            try
            {
                res = OutcomeItemsDAO.InsertOutcomeItem(oi);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error inserting outcome item", ex);
                res = false;
            }
            return res;
        }

        public bool UpdateOutcomeItem(OutcomeItem oi)
        {
            bool res = false;
            try
            {
                res = OutcomeItemsDAO.UpdateOutcomeItem(oi);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error updating outcome item", ex);
                res = false;
            }
            return res;
        }
        #endregion

        #region UserOutcome

        public bool InsertUserOutcome(UserOutcome uo)
        {
            bool res = false;
            try
            {
                res = UserOutcomeDAO.InsertUserOutcome(uo);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error inserting outcome item", ex);
                res = false;
            }
            return res;
        }

        public bool UpdateUserOutcome(UserOutcome uo)
        {
            bool res = false;
            try
            {
                res = UserOutcomeDAO.UpdateUserOutcome(uo);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error updating outcome item", ex);
                res = false;
            }
            return res;
        }

        public bool DeleteUserOutcome(UserOutcome uo)
        {
            bool res = false;
            try
            {
                res = UserOutcomeDAO.DeleteUserOutcome(uo);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error deleting outcome item", ex);
                res = false;
            }
            return res;
        }

        public bool InsertUserOutcomeList(List<UserOutcome> list)
        {
            bool res = false;
            try 
            {
                res = UserOutcomeDAO.InsertListUserUoutcome(list);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Erorr insertign list of outcome items", ex);
                res = false;
            }
            return res;
        }
        #endregion

        #region OutcomeDay
        public OutcomeDay LoadOutcomeDay(DateTime day, int userID)
        {
            OutcomeDay res = new OutcomeDay();
            res.Date = day.Date;
            res.DayName = day.DayOfWeek.ToString();
            try
            {
                string where = String.Format(" WHERE DATE = '{0}' AND USERID = {1}", res.Date, userID);
                res.OutcomeList = UserOutcomeDAO.LoadUserOutcomeList(where);
                res.Total = OutcomeDayDAO.GetDayTotal(res.Date);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading outcome day", ex);
            }
            return res;
        }

        public List<OutcomeDay> LoadOutcomeWeek(DateTime day, int userID)
        {
            List<OutcomeDay> res = new List<OutcomeDay>();
            while (day.DayOfWeek != DayOfWeek.Monday)
            {
                day = day.AddDays(-1);
            }
            for (int i = 0; i < 7; i++)
            {
                OutcomeDay od = LoadOutcomeDay(day, userID);
                res.Add(od);
                day = day.AddDays(1);
            }
            return res;
        }

        public List<OutcomeDay> LoadOutcomeMonth(DateTime day, int userID)
        {
            List<OutcomeDay> res = new List<OutcomeDay>();
            int currentMonth = day.Month;
            while (day.Month == currentMonth)
            {
                day = day.AddDays(-1);
            }
            day = day.AddDays(1);
            while (day.Month == currentMonth)
            {
                OutcomeDay od = LoadOutcomeDay(day, userID);
                res.Add(od);
                day = day.AddDays(1);
            }
            return res;
        }

        public List<OutcomeDay> LoadOutcomeRange(DateTime startDay, DateTime endDay, int userID)
        {
            List<OutcomeDay> res = new List<OutcomeDay>();
            while (startDay.Date <= endDay.Date)
            {
                OutcomeDay od = LoadOutcomeDay(startDay, userID);
                res.Add(od);
                startDay = startDay.AddDays(1);
            }
            return res;
        }

        #endregion 

        #region reporting
        public DataSet GetMonthlyReport(DateTime day)
        {
            DataSet res = null;
            int currentMonth = day.Month;
            while (day.Month == currentMonth)
            {
                day = day.AddDays(-1);
            }
            day = day.AddDays(1);
            DateTime startDate = day;
            while (day.Month == currentMonth)
            {
                day = day.AddDays(1);
            }
            DateTime endDate = day.AddDays(-1);
            try
            {
                res = ReportsDAO.GetAllItemsMonthlyReport(startDate, endDate);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error monthly report day", ex);
            }
            return res;
        }
        #endregion

        #region ImportItem

        public bool SaveImportedItemsList(List<Importitem> list)
        {
            bool res = false;
            try
            {
                if (list.Count > 0)
                {
                    bool insert = list[0].Importitemid == null;
                    if (insert)
                    {
                        res = ImportitemDAO.InsertListImportitem(list);
                    }
                    else
                    {
                        res = ImportitemDAO.UpdateListImportitem(list);
                    }
                }
            }
            catch (Exception ex)
            {
                res = false;
                LogManager.LogException("Error saving imported items list", ex);
            }
            return res;
        }

        public List<Importitem> LoadImportItemsList()
        {
            List<Importitem> res = null;
            try
            {
                res = ImportitemDAO.LoadImportitems("", "");
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading imported item", ex);
                res = null;
            }
            return res;
        }

        public bool DeleteListImportitem(List<Importitem> list)
        {
            bool res = false;
            try
            {
                res = ImportitemDAO.DeleteListImportitem(list);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error deleting import itsms list", ex);
                res = false;
            }
            return res;
        }
        #endregion

        #region EuroCourse
        public Dictionary<DateTime, Decimal?> LoadEuroCourse(DateTime startDate, DateTime endDate)
        {
            Dictionary<DateTime, Decimal?> res = new Dictionary<DateTime,decimal?>();
            try
            {
                string where = String.Format(" WHERE DATE >= '{0}' AND DATE <= '{1}'", startDate, endDate);
                res = EuroDAO.LoadEuroCourse(where);
            }
            catch (Exception ex)
            {
                LogManager.LogException("Error loading euro course", ex);
            }
            return res;
        }

        public bool UpdateEuro(Euro euro)
        {
            bool res = false;
            try
            {
                res = EuroDAO.SaveEuro(euro);
            }
            catch (Exception ex)
            {
                res = false;
                LogManager.LogException("Error updating euro course", ex);
            }
            return res;
        }

        public decimal LoadEuroCourseDay(DateTime date)
        {
            decimal res = 0;
            try
            {
                res = EuroDAO.GetEuroCourse(date);
            }
            catch (Exception ex)
            {
                res = 0;
                LogManager.LogException("Error getting euro course", ex);
            }
            return res;
        }
        #endregion

        #region Common
        public DateTime GetFirstDate(long userID)
        {
            DateTime res = DateTime.Today;
            try
            {
                res = CommonDAO.GetFirstEnterenceDate(userID);
            }
            catch (Exception ex)
            {
                res = DateTime.Today;
                LogManager.LogException("Unable to retreive first date", ex);
            }
            return res;
        }

        public DateTime GetLastDate(long userID)
        {
            DateTime res = DateTime.Today;
            try
            {
                res = CommonDAO.GetLastEnterenceDate(userID);
            }
            catch (Exception ex)
            {
                res = DateTime.Today;
                LogManager.LogException("Unable to retreive last date", ex);
            }
            return res;
        }

        #endregion 
    }
}
